#include "Comm.hpp"
#include "TcpServer.hpp"
#include <thread>
const static vector<const char*> EMOS = {"正常(长)","期待","惊呆","困惑","开心","冷漠","喜欢","悲伤","无语","打招呼","生气","疼痛","疲惫","委屈","享受","眩晕","正常(短)","未知"};
const static vector<const char*> ACTIONS = {"正常站立","走","跑","左转","右转","停止","俯卧撑","蹲起","扭屁股","打招呼","滑步","跳舞","mini步","太空步","趴下","坐下"
,"握手","碰拳","左边转圈","右边转圈","后退","靠近","转身"};
const static vector<const char*> VOICES = {"无","左转","右转","前进","后退","趴下","坐下","跳舞","俯卧撑","打招呼","跳跃","碰拳","握手","正确","错误","太空步","停止","转圈","靠近","跑","滑步","向后转","退出"};
const static vector<const char*> POSES = { "无","碰拳","生气","开心","错误","坐下","打招呼","夸赞","枪击","再见","鄙视","赞同","激怒","同意","喜欢","跳舞" };
const static vector<const char*> NAMES = { "ChenGuo","ChenYJ","DaBing","FuCheng","KouZY","LiangDW","LiuBing","Rambo","TuJian","YanCL","ZhuXH"};
bool t_flag = false;//追踪写入
bool d_flag = false;//决策
bool v_flag = true;//语音连接
bool c_flag = true;//视频连接
bool F_flag = true;//追踪连接
static RobotDec::Desion my_desion;
void get_point(Connection *conn)
{
    Response result;
    result._mode = 5;
    result._expression = "set fail";
    while (t_flag)
    {
        int point = 0;
        if(!(conn->_tsvr->_rqp->is_empty()))
            conn->_tsvr->_rqp->pop(&point);
        result._res = point;  
        if (point != 0)
        {
            result._expression = "set success";
            // logMessage(NORMAL, "Read Point success");
            std::string res = result.Serialize();
            res = EnCode(res);
            conn->_outbuffer += res;
            //logMessage(NORMAL,"point:%d\n",point);
            conn->_tsvr->EnableReadWrite(conn, true, true);
            if(point==65535)
            {
                logMessage(NORMAL,"人脸追踪服务端退出");
                //conn->_tsvr->_rqp->Clear();
                // sleep(2);
                // if (conn->_tsvr->_rqp!=nullptr)
                // {
                //     delete conn->_tsvr->_rqp;
                //     conn->_tsvr->_rqp=nullptr;
                // }
                break;
            }
        }
        // logMessage(NORMAL,"写入");
    }
}
void Pre_training1(bool flag)
{
    vector<pair<int, int>> r;
    if(flag)
    {
        //友好性格预训练
        r = { {0,1},{12,0},{7,15},{0,7},{0,10}};
    }
    else
    {
        //敌对性格预训练
        r = { {8,0},{0,10},{0,12},{0,8},{12,0} };
    }
    int k=0;
    while(k<1)//轮次
    {
        k++;
        int j=1;
        int t = 100;
        while(j<=15)//身份
        {
            int i =0;
            while(i<300)//交互次数
            {
                Response result;
                RobotDec::Input inp;
                inp._name = j+t;
                int dex = RobotDec::RangProbability(0,4);//参数0-4的随机下标
                inp._voice = r[dex].first;
                inp._pose = r[dex].second;
                bool res = my_desion.Start(inp,&result);
                if (!res)
                {
                    result._expression += " 忽略，没有决策!";
                }
                else {
                    result._expression += " 决策成功!";
                }
                i++;
            }
            j++;
        }
        j=1;
        r = {{9,6},{18,0},{7,15},{0,11},{4,0},{0,10},{0,12},{8,0}};
        while(j<10)
        {
            int i=0;
            
            while(i<110)//交互次数
            {
                Response result;
                RobotDec::Input inp;
                inp._name = j;
                int dex = RobotDec::RangProbability(0,7);//参数0-4的随机下标
                inp._voice = r[dex].first;
                inp._pose = r[dex].second;
                bool res = my_desion.Start(inp,&result);
                if (!res)
                {
                    result._expression += " 忽略，没有决策!";
                }
                else {
                    result._expression += " 决策成功!";
                }
                i++;
            }
            j++;
        }
    }
    if(flag) logMessage(NORMAL, "Friendly personality pre-training completed,%lf",my_desion._avg_personality);
    else logMessage(NORMAL, "Hostile character pre-training completed,%lf",my_desion._avg_personality);

}
void Pre_training2(bool flag)
{
    

}
void get_desion(Connection *conn)
{
   
    //预训练
    Pre_training1(true);
    //
    bool is_send = false;
    size_t history_name = 100;
    time_t star_time_1 = 0;
    time_t cur_time_1 = 0;
    time_t star_time_2 = 0;
    time_t cur_time_2 = 0;
    std::string str;
    bool flag = true;
    while(d_flag)
    {
        Response result;
        //logMessage(NORMAL,"执行循环,并创建应答");
        //str = "";
        RobotDec::Input inp;
        size_t n_p=255;
        if(!(conn->_tsvr->_rqc->is_empty()))
            conn->_tsvr->_rqc->pop(&n_p);
        if(!(conn->_tsvr->_rqv->is_empty()))
            conn->_tsvr->_rqv->pop(&inp._voice);
        if(inp._voice == ORDER_EXIT)
        {
            //通知对面结束
            string rs = "50_255_exit";
            conn->_outbuffer +=rs;
            conn->_tsvr->EnableReadWrite(conn, true, true);
            logMessage(NORMAL,"执行动作服务端退出");
            break;
        }
        inp._pose = n_p>>16;
        inp._name = n_p& 0xFFFF;
        if(inp._pose == HANDER_UNKNOW && inp._voice == ORDER_UNKNOW)
        {
            cur_time_1 = time(NULL);
            //大于1分钟未检测到人脸
            if(cur_time_1-star_time_1>60)
            {
                star_time_1 = cur_time_1;
                inp._pose = HANDER_UNKNOW;
                inp._voice = ORDER_UNKNOW;
                is_send = true;
            }
        }
        else 
        {
            //有交互命令
            if(inp._name == NAME_UNKNOW )
            {
                //没有人脸
                inp._name = history_name;
            }
            else
            {
                //有人脸
                history_name = inp._name;
            }
            is_send = true;
        }
        // if(inp._name == NAME_UNKNOW)
        // {
        //     //logMessage(NORMAL,"NAME == UNKNOW");
        //     star_time_2 = 0;
        //     if(star_time_1==0)
        //     {
                
        //         star_time_1 = time(NULL);
        //         logMessage(NORMAL,"star_time_1==0,NEW startime==%d",star_time_1);
        //         is_send = true;
        //     }
        //     else
        //     {
        //         //logMessage(NORMAL,"star_time_1!=0");
        //         cur_time_1 = time(NULL);
        //         if(cur_time_1-star_time_1 >= FREE_TIME_TWO)
        //         {
        //             logMessage(NORMAL,"空闲两分钟");
        //             star_time_1 = cur_time_1;
        //             is_send = true;
        //         }
        //         else
        //         {
        //             //logMessage(NORMAL,"没有空闲两分钟");
        //             is_send = false;
        //         }
        //     }
        //     //logMessage(NORMAL,"无效交互信息");
        // }
        // else
        // {
        //     star_time_1 = 0;
        //     //logMessage(NORMAL,"正常交互命令");
        //     if(inp._pose==HANDER_UNKNOW && inp._voice == ORDER_UNKNOW && flag)
        //     {
        //         is_send = true;
        //         flag = false;
        //     }
        //     else if(0==star_time_2)
        //     {
        //         logMessage(NORMAL,"star_time_2==0,star:%d",star_time_2);
        //         star_time_2 = time(NULL);
        //         logMessage(NORMAL,"star_time_2==0,newstar2:%d",star_time_2);
        //         flag = true;
        //     }
        //     else
        //     {
        //         flag = true;
        //         //logMessage(NORMAL,"star_time_2!=0");
        //         if(inp._pose!=HANDER_UNKNOW || inp._voice != ORDER_UNKNOW)
        //         {
        //             //logMessage(NORMAL,"pose!=UNKNOW || ORDER!=UNKNOW. pose:%d,order:%d",inp._pose,inp._voice);
        //             is_send = true;
        //         }
        //         else
        //         {
        //             //logMessage(NORMAL,"pose && order == unknow");
        //             cur_time_2 = time(NULL);
        //             if(cur_time_2-star_time_2>=10)
        //             {
        //                 logMessage(NORMAL,"10秒间隔,cur:%d,star:%d",cur_time_2,star_time_2);
        //                 star_time_2 = cur_time_2;
        //                 is_send = true;
        //             }
        //             else
        //             {
        //                 //logMessage(NORMAL,"交互时间间隔太短，不进行反应");
        //                 is_send = false;
        //             }
        //         }
        //     }   
        //}
        if(is_send)
        {
            //logMessage(NORMAL,"is_send==true");
            logMessage(NORMAL,"交互命令：name:%s,pose:%s,order:%s",NAMES[inp._name],POSES[inp._pose],VOICES[inp._voice]);
            bool res = my_desion.Start(inp,&result);
            if(!res)
            {
                result._expression += " 忽略，没有决策!";
            }
            else
            {
                result._expression += " 决策成功!";
            }
            if(result._mode ==255 && result._res==255)
            {
                is_send = false;
                logMessage(NORMAL,"无效反应");
                continue;    
            }
            str = result.Serialize();
            str = EnCode(str);
            logMessage(NORMAL,"决策动作：动作:%s,表情:%s",ACTIONS[result._mode% 23],EMOS[result._res% 17]);
            //logMessage(NORMAL, str.c_str());
            conn->_outbuffer += str;
            conn->_tsvr->EnableReadWrite(conn, true, true);
            str = "";
            logMessage(NORMAL,"决策并发送,str清空,%s",str.c_str());
            is_send = false;
            
        }
        // if(str!="")
        // {    
        //     conn->_outbuffer += str;
        //     conn->_tsvr->EnableReadWrite(conn, true, true);
        // }
        sleep(1);   
    }
}
Response CarryOut(Request &req, Connection *conn)
{
    // logMessage(NORMAL,"%d %d ",req._mode,req._decision);
    Response res;
    res._mode = req._mode;
    if (res._mode == 5)
    {
        if(F_flag)
        {
            res._res = req._decision;
            if (conn->_tsvr->_rqp==nullptr)
            {
                conn->_tsvr->_rqp = new RingQueue<int>;
                logMessage(NORMAL, "5-1:conn->_tsvr->_rqp:%p",conn->_tsvr->_rqp);
            }
            logMessage(NORMAL, "face_track link success");
            F_flag = false;
        }
    }
    if(res._mode == 6)
    {
        logMessage(NORMAL, "robot contral link success");
    }
    // logMessage(NORMAL, "MODE:%d", req._mode);
    // logMessage(NORMAL, "DES:%d", req._decision);
    int point_x = req._point_x;
    int point_y = req._point_y;

    if (req._mode == 1) // 摄像头数据
    {
        if(c_flag)
        {
            logMessage(NORMAL,"摄像头数据连接成功");
            if (conn->_tsvr->_rqc==nullptr)
            {
                conn->_tsvr->_rqc = new RingQueue<size_t>;
                logMessage(NORMAL, "1:conn->_tsvr->_rqc:%p",conn->_tsvr->_rqc);
            }
            if (conn->_tsvr->_rqp==nullptr)
            {
                conn->_tsvr->_rqp = new RingQueue<int>;
                logMessage(NORMAL, "1:conn->_tsvr->_rqp:%p",conn->_tsvr->_rqp);
            }
            c_flag = false;
        }
        // logMessage(NORMAL,"获得摄像头数据");
        if(req._decision!=0)
        {
            //logMessage(NORMAL, "摄像头数据，人名：%d ,手势：%d ", (req._decision & 0xFFFF),(req._decision) >> 16 );
            if(!(conn->_tsvr->_rqc->is_full()))
                conn->_tsvr->_rqc->push(req._decision);
        }
        // else
        // {
        //     //conn->_tsvr->_rqc->push(Dec::NAME_UNKNOW<<16);
        //     //sleep(0.5);
        // }
        
        if (point_x != -1 && point_y != -1)
        {
            int point = (point_x << 16) | (point_y);
            // x,y为有效数据，将其放入坐标环形队列中
            //logMessage(NORMAL, "x:y->(%d,%d)", req._point_x, req._point_y);
            if(!(conn->_tsvr->_rqp->is_full()))
                conn->_tsvr->_rqp->push(point);
        }
    }
    if (req._mode == 2) // 声频数据
    {
        if(v_flag)
        {
            logMessage(NORMAL,"音频数据已连接");
            if(conn->_tsvr->_rqv==nullptr)
            {
                conn->_tsvr->_rqv = new RingQueue<size_t>;
                logMessage(NORMAL, "2:conn->_tsvr->_rqv:%p",conn->_tsvr->_rqv);
            }
            v_flag = false;
        }
        if(req._decision!=0)
        {    
            logMessage(NORMAL, "音频数据，命令：%d ", req._decision);
            if(!(conn->_tsvr->_rqv->is_full()))
                conn->_tsvr->_rqv->push(req._decision);
        }
        // else
        // {
        //     //conn->_tsvr->_rqv->push(0);
        //     //sleep(0.5);
        // }
        
    }
    // if (req._mode == 3) // 触觉数据
    // {
    //     if(req._decision!=0)
    //     {
    //         logMessage(NORMAL, "触觉：%s ", req._decision == 1 ? "true" : "false");
    //         // conn->_tsvr->_rqt->push(req._decision);
    //     }
    //     else
    //     {
    //         conn->_tsvr->_rqt->push(0);
    //     }
    // }
    return res;
}
void NetCal(Connection *conn, std::string &request)
{
    logMessage(DEBUG, "NetCal been called,get a message: %s", request.c_str());
    // 1.反序列化
    Request req;
    if (!req.Deserialize(request))
        return;

    // 2.业务处理
    if (req._mode == 0)
    {
        logMessage(NORMAL,"%s",req.Serialize().c_str());
        if(req._decision==1) 
        {
            logMessage(NORMAL, "视频资源已清理");
            if(conn->_tsvr->_rqc!=nullptr)
            {
                delete conn->_tsvr->_rqc;
                conn->_tsvr->_rqc==nullptr;
            }
            c_flag = true;
        }
        if(req._decision==2) 
        {
            logMessage(NORMAL, "语音资源已清理");
            if(conn->_tsvr->_rqv!=nullptr)
            {
                delete conn->_tsvr->_rqv;
                conn->_tsvr->_rqv = nullptr;
            }
            v_flag = true;
        }
        if(req._decision==5) 
        {
            logMessage(NORMAL, "追踪资源已清理");
            if(conn->_tsvr->_rqp!=nullptr)
            {
                delete conn->_tsvr->_rqp;
                conn->_tsvr->_rqp = nullptr;
            }
        }
        return;
    }
    Response resp = CarryOut(req, conn);

    // 3.序列化构建应答
    if (!t_flag && resp._mode == 5)
    {
        t_flag = true;
        if (conn->_tsvr->_rqp==nullptr)
        {
            conn->_tsvr->_rqp = new RingQueue<int>;
            logMessage(NORMAL, "5:conn->_tsvr->_rqp:%p",conn->_tsvr->_rqp);
        }
        // mode==5 表示为跟踪系统，创建线程不断的从环形队列中提取数据
        std::thread t(get_point, conn);
        t.detach();
        // 让底层的TcpServer开启该sock的写入方法
        conn->_tsvr->EnableReadWrite(conn, true, true);
        logMessage(NORMAL, "face_track write start");
    }
    if(!d_flag &&resp._mode == 6)
    {
        //mode==6 表示执行端服务器，需要创建线程去执行决策函数将决策结果发送给执行端
        d_flag = true;
        if (conn->_tsvr->_rqc==nullptr)
        {
            
            conn->_tsvr->_rqc = new RingQueue<size_t>;
            logMessage(NORMAL, "6:conn->_tsvr->_rqc:%p",conn->_tsvr->_rqc);
        }
        if (conn->_tsvr->_rqv==nullptr)
        {
            conn->_tsvr->_rqv = new RingQueue<size_t>;
            logMessage(NORMAL, "6:conn->_tsvr->_rqv:%p",conn->_tsvr->_rqv);
        }
        std::thread t(get_desion, conn);
        t.detach();
        // 让底层的TcpServer开启该sock的写入方法
        conn->_tsvr->EnableReadWrite(conn, true, true);
        logMessage(NORMAL, "desion write start");
    }
}

int main()
{
    signal(SIGCHLD, SIG_IGN);
    TcpServer *sevptr = new TcpServer;
    sevptr->Dispather(NetCal);
    return 0;
}